Memory Alignment
CPU 以 word 為單位讀取,變數的起始位置通常是自身大小的倍數,否則可能要讀兩個 word。
Struct 規則
- alignment = 最寬成員的 alignment
- 成員之間補 padding 以滿足各自的 alignment
- 尾端補 padding,讓
sizeof是 alignment 的倍數(當作陣列時仍對齊) - padding 的內容不保證是 0
c
struct bar { // sizeof = 24
char c; // 1 + 7 padding
uint64_t v1; // 8
uint16_t v2; // 2 + 6 padding
};
struct bar2 { // sizeof = 16
uint64_t v1;
uint16_t v2;
char c; // 尾端 5 padding
};減少 padding
- 由大到小排列成員;代價是可讀性,以及相關欄位分開可能影響 cache
__attribute__((packed)):完全不補 padding,存取可能變慢或在某些架構上出錯
檢查
sizeof(T)、offsetof(T, member)、alignof(T)- Go 不支援 packed struct,cgo 需注意(cgo wiki)